package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.mq.websocket.server.PCWsChannelServer;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.AwardAgentDTO;
import com.fjwt.gz.db.dto.AwardAllocationAgentDTO;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.db.dto.*;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.AwardAgentVO;
import com.fjwt.gz.service.mapper.AwardAgentMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 奖品机构对应关系表(派发/激活)/机构活动渠道表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class AwardAgentService extends ServiceImpl<AwardAgentMapper, AwardAgentEntity> {

    @Autowired
    private AwardGoodsService awardGoodsService;
    @Autowired
    private AwardCouponService awardCouponService;
    @Autowired
    private AwardScoreService awardScoreService;
    @Autowired
    private AwardVirtualService awardVirtualService;
    @Autowired
    private ActivityAwardService activityAwardService;
    @Autowired
    private AwardSettingService awardSettingService;
    @Autowired
    private OssRecordService ossRecordService;
    @Autowired
    private AgentInfoService agentInfoService;
    @Autowired
    private PCWsChannelServer pcWsChannelServer;

    /**
     * 获取列表
     */
    public IPage<AwardAgentVO> getList(IPage iPage, AwardAgentDTO awardAgentDTO) {
        if (awardAgentDTO.getAwardId() == null || awardAgentDTO.getAwardType() == null) {
            throw new BizException("请求参数异常，请检查！");
        }
        AgentInfoEntity agentInfo = agentInfoService.getById(awardAgentDTO.getAgentNo());
        if (agentInfo != null) {
            awardAgentDTO.setLevel(agentInfo.getLevel());
        }
        return baseMapper.getListByAgentNo(iPage, awardAgentDTO);
    }

    /**
     * 批量插入
     */
    @Transactional
    public void addByBatch(AwardAllocationAgentDTO dto) {
        if (dto.getAwardId() == null || dto.getAwardType() == null
                || CollUtil.isEmpty(dto.getList())) {
            throw new BizException("请求参数异常，请检查！");
        }
        List<AwardAgentEntity> list = commonCheck(dto, false);
        saveBatch(list);
    }

    /**
     * 批量修改（数量、机构只能增加，不能减少）
     */
    @Transactional
    public void updateByBatch(AwardAllocationAgentDTO dto) {
        if (dto.getAwardId() == null || dto.getAwardType() == null
                || CollUtil.isEmpty(dto.getList())) {
            throw new BizException("请求参数异常，请检查！");
        }
        List<AwardAgentEntity> newList = commonCheck(dto, true);
        saveOrUpdateBatch(newList);
    }

    /**
     * 批量修改（数量、机构只能增加，不能减少）
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateByBatch(AwardAllocationAgentDTO awardAllocationAgentDTO, boolean isUpdate) {
        List<AwardAgentEntity> newList = commonCheck(awardAllocationAgentDTO, isUpdate);
        try {
            saveOrUpdateBatch(newList);
        } catch (Exception e) {
            log.error("保存或更新奖品机构分配数据异常", e);
            throw new BizException("奖品机构分配数据入库异常");
        }
    }

    /**
     * 通用检查
     *
     * @return
     */
    private List<AwardAgentEntity> commonCheck(AwardAllocationAgentDTO awardAllocationAgentDTO, boolean isUpdate) {
        log.info("奖品配置机构，前端传参:{}", JSONUtil.toJsonStr(awardAllocationAgentDTO));
        //是否限制下级机构分配
        boolean isAllocation = !CollectionUtils.isEmpty(awardAllocationAgentDTO.getList());
        final Long awardId = awardAllocationAgentDTO.getAwardId();
        final Integer awardType = awardAllocationAgentDTO.getAwardType();
        Object awardObject = null;
        Integer awardNum = null;
        Integer awardState = null;
        String rootAgentNo = "";
        //是否限制可派发/激活机构（0否，1是；默认0）
        int YES = 1;
        switch (awardType) {
            case Constants.AWARD.COUPON:
                AwardCouponEntity awardCouponEntity = awardCouponService.getById(awardId);
                if (awardCouponEntity != null) {
                    awardState = awardCouponEntity.getState();
                    awardNum = awardCouponEntity.getCouponNum();
                    rootAgentNo = awardCouponEntity.getAgentNo();
                }
                awardObject = awardCouponEntity;
                break;
            case Constants.AWARD.GOODS:
                AwardGoodsEntity awardGoodsEntity = awardGoodsService.getById(awardId);
                if (awardGoodsEntity != null) {
                    awardState = awardGoodsEntity.getState();
                    awardNum = awardGoodsEntity.getGoodsNum();
                    rootAgentNo = awardGoodsEntity.getAgentNo();
                }
                awardObject = awardGoodsEntity;
                break;
            case Constants.AWARD.SCORE:
                AwardScoreEntity awardScoreEntity = awardScoreService.getById(awardId);
                if (awardScoreEntity != null) {
                    awardState = awardScoreEntity.getState();
                    awardNum = awardScoreEntity.getScoreNum();
                    rootAgentNo = awardScoreEntity.getAgentNo();
                }
                awardObject = awardScoreEntity;
                break;
            case Constants.AWARD.VIRTUAL_COUPON:
                AwardVirtualEntity awardVirtualEntity = awardVirtualService.getById(awardId);
                if (awardVirtualEntity != null) {
                    awardState = awardVirtualEntity.getState();
                    awardNum = awardVirtualEntity.getGoodsNum();
                    rootAgentNo = awardVirtualEntity.getAgentNo();
                }
                awardObject = awardVirtualEntity;
                break;
            default:
                throw new BizException("奖品类型错误!");
        }
        if (awardObject == null) {
            throw new BizException("该奖品不存在！");
        }
        if (isAllocation) {
            AwardSettingEntity awardSetting = awardSettingService.getOne(AwardSettingEntity.gw()
                    .eq(AwardSettingEntity::getAwardId, awardId)
                    .eq(AwardSettingEntity::getAwardType, awardType));
            if (awardSetting != null) {
                awardSetting.setIsAllocation(YES);
                awardSettingService.updateById(awardSetting);
            }
        }

        if (awardNum == null) {
            throw new BizException("该奖品配置数量不存在！");
        }
        log.info("奖品配置机构，数据库中数量：{}", awardNum);

//        final AwardAgentAllocationDTO awardAgent = awardAllocationAgentDTO.getList().get(0);
//        final Integer requestAwardNum = awardAgent.getNum();
//        if (awardNum == null || requestAwardNum == null) {
//            throw new BizException("该奖品配置数量不存在！");
//        }
//        log.info("奖品配置机构，前端根节点数量：{},数据库中数量：{}", requestAwardNum, awardNum);
//        if (requestAwardNum.intValue() != awardNum.intValue()) {
//            throw new BizException("该奖品分配的总数量不等于实际数量！");
//        }

        List<String> allSubAgentNo = agentInfoService.queryAllSubAgentNo(rootAgentNo);
        List<AwardAgentEntity> newList = treeToList(awardAllocationAgentDTO.getList(), awardId, awardType, awardNum, rootAgentNo, allSubAgentNo);

        if (CollUtil.isNotEmpty(newList)) {
            Map<String, AwardAgentEntity> newMap = newList.stream().collect(Collectors.toMap(AwardAgentEntity::getAgentNo, entity -> entity));
            if (!newMap.containsKey(rootAgentNo)) {
                AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(rootAgentNo);
                int sum = awardAllocationAgentDTO.getList().stream().mapToInt(AwardAgentAllocationDTO::getNum).sum();
                AwardAgentEntity rootAwardAgent = new AwardAgentEntity();
                rootAwardAgent.setAgentNo(rootAgentNo)
                        .setNum(awardNum)
                        .setNumAllocation(sum)
                        .setAwardId(awardId)
                        .setAwardType(awardType)
                        .setAgentNo1(agentInfo.getAgentNo1())
                        .setAgentNo2(agentInfo.getAgentNo2())
                        .setAgentNo3(agentInfo.getAgentNo3())
                        .setAgentNo4(agentInfo.getAgentNo4())
                        .setIsChannelDisplay(1);
                newList.add(rootAwardAgent);
                AwardAgentEntity awardAgentEntity = getOne(AwardAgentEntity.gw()
                        .eq(AwardAgentEntity::getAwardId, awardId)
                        .eq(AwardAgentEntity::getAwardType, awardType)
                        .eq(AwardAgentEntity::getAgentNo, rootAgentNo));
                if (awardAgentEntity != null) {
                    rootAwardAgent.setAwardAgentId(awardAgentEntity.getAwardAgentId());
                    isUpdate = true;
                }
            }
        }
        if (isUpdate) {
            boolean isDelete = false;//是否可以被删除
            if (awardState == null) {
                throw new BizException("该奖品配置状态异常！");
            }
            if (awardState == Constants.AWARD_STATE.DRAFT) {
                isDelete = true;
            }
            if (awardState == Constants.AWARD_STATE.OFFLINE) {
                LambdaQueryWrapper<ActivityAwardEntity> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ActivityAwardEntity::getAwardId, awardId);
                wrapper.eq(ActivityAwardEntity::getAwardType, awardType);
                List<ActivityAwardEntity> list = activityAwardService.list(wrapper);
                if (list.isEmpty()) {
                    isDelete = true;
                }
            }
            Map<String, Integer> newMap = newList.stream().collect(Collectors.toMap(AwardAgentEntity::getAgentNo, AwardAgentEntity::getNum));
            List<AwardAgentEntity> oldList = getSavedData(awardAllocationAgentDTO.getAwardId(), awardAllocationAgentDTO.getAwardType());
            Map<String, Integer> oldMap = oldList.stream().collect(Collectors.toMap(AwardAgentEntity::getAgentNo, AwardAgentEntity::getNum));
            for (String agentNo : oldMap.keySet()) {
                // 支持新增机构，不支持删除机构
                if (newMap.containsKey(agentNo)) {
                    if (!isDelete && newMap.get(agentNo) < oldMap.get(agentNo)) {
                        throw new BizException("已分配的机构数量不能减少！");
                    }
                } else {
                    if (!isDelete) {
                        throw new BizException("不能删除已分配的机构！");
                    } else {
                        LambdaQueryWrapper<AwardAgentEntity> removeWrapper = new LambdaQueryWrapper<>();
                        removeWrapper.eq(AwardAgentEntity::getAwardId, awardId);
                        removeWrapper.eq(AwardAgentEntity::getAwardType, awardType);
                        removeWrapper.eq(AwardAgentEntity::getAgentNo, agentNo);
                        remove(removeWrapper);
                    }
                }
            }
        }
        log.info("奖品配置机构，后端修改后的数据:{}", JSONUtil.toJsonStr(newList));
        return newList;
    }

    /**
     * 获取已保存的数据
     *
     * @return
     */
    public List<AwardAgentEntity> getSavedData(Long awardId, Integer awardType) {
        LambdaQueryWrapper<AwardAgentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AwardAgentEntity::getAwardId, awardId);
        wrapper.eq(AwardAgentEntity::getAwardType, awardType);
        return list(wrapper);
    }

    /**
     * 删除已保存的数据
     *
     * @return
     */
    @Transactional
    public void removeSavedData(AwardAgentDTO awardAgentDTO) {
        Long awardId = awardAgentDTO.getAwardId();
        Integer awardType = awardAgentDTO.getAwardType();
        if (awardId == null || awardType == null) {
            throw new BizException("请求参数异常，请检查！");
        }
        List<ActivityAwardEntity> list = activityAwardService.list(ActivityAwardEntity.gw()
                .eq(ActivityAwardEntity::getAwardId, awardId)
                .eq(ActivityAwardEntity::getAwardType, awardType));
        if (!list.isEmpty()) {
            throw new BizException("该奖品已配置活动，不能删除！");
        }

        String errorMsg = "";
        switch (awardType) {
            case Constants.AWARD.COUPON:
                AwardCouponEntity awardCouponEntity = awardCouponService.getById(awardId);
                if (awardCouponEntity == null || awardCouponEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.GOODS:
                AwardGoodsEntity awardGoodsEntity = awardGoodsService.getById(awardId);
                if (awardGoodsEntity == null || awardGoodsEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.SCORE:
                AwardScoreEntity awardScoreEntity = awardScoreService.getById(awardId);
                if (awardScoreEntity == null || awardScoreEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.VIRTUAL_COUPON:
                AwardVirtualEntity awardVirtualEntity = awardVirtualService.getById(awardId);
                if (awardVirtualEntity == null || awardVirtualEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
        }

        if (!errorMsg.isEmpty()) {
            throw new BizException(errorMsg);
        }
        LambdaQueryWrapper<AwardAgentEntity> removeWrapper = new LambdaQueryWrapper<>();
        removeWrapper.eq(AwardAgentEntity::getAwardId, awardId);
        removeWrapper.eq(AwardAgentEntity::getAwardType, awardType);
        boolean isUpdate = remove(removeWrapper);
        if (isUpdate) {
            //更新是否限制字段信息
            AwardSettingEntity awardSetting = new AwardSettingEntity();
            awardSetting.setAwardId(awardId);
            awardSetting.setAwardType(awardType);
            awardSetting.setIsAllocation(0);
            awardSettingService.updateById(awardSetting);
        }
    }


    /**
     * 将树形结构转换为链表
     *
     * @param awardAgentList
     * @param allSubAgentNo
     * @return
     */
    private List<AwardAgentEntity> treeToList(List<AwardAgentAllocationDTO> awardAgentList, final Long awardId, final Integer awardType, int totalNum, String agentNo, List<String> allSubAgentNo) {
        Date date = new Date();
        List<AwardAgentEntity> entityList = new ArrayList<>();
        //总数量
        int num = 0;
        for (AwardAgentAllocationDTO item : awardAgentList) {
            num += item.getNum();
            String currAgentNo = item.getAgentNo();
            if (!allSubAgentNo.contains(currAgentNo)) {
                throw new BizException("所导入数据中有不符合要求的机构网点：" + currAgentNo);
            }

            AwardAgentEntity entity = new AwardAgentEntity();
            BeanUtils.copyProperties(item, entity);
            if (ObjectUtils.isEmpty(entity.getAgentNo1())) {
                entity.setAgentNo1("0");
            }
            if (ObjectUtils.isEmpty(entity.getAgentNo2())) {
                entity.setAgentNo2("0");
            }
            if (ObjectUtils.isEmpty(entity.getAgentNo3())) {
                entity.setAgentNo3("0");
            }
            if (ObjectUtils.isEmpty(entity.getAgentNo4())) {
                entity.setAgentNo4("0");
            }
            entity.setCreatedAt(date);
            entity.setAwardId(awardId);
            entity.setAwardType(awardType);
            entity.setAwardAgentId(item.getAwardAgentId());
            entity.setIsChannelDisplay(item.getIsChannelDisplay());
            if (item.getChildren() != null && !item.getChildren().isEmpty()) {
                //获取子机构分配的数量和
                int childrenNum = item.getChildren().stream().mapToInt(AwardAgentAllocationDTO::getNum).sum();
                //分配给下一级的数量
                entity.setNumAllocation(childrenNum);
                entityList.addAll(treeToList(item.getChildren(), awardId, awardType, item.getNum(), item.getAgentNo(), allSubAgentNo));
            }
            entityList.add(entity);
        }
        log.info(String.format("当前机构号：%s, 分配的总数量： %s,下级配置的总数量：%s", agentNo, totalNum, num));
        if (num > totalNum) {
            throw new BizException("下级机构分配数量不能大于上级！");
        }
        return entityList;
    }

    /**
     * 根据excel导入分配机构数量数据
     *
     * @param allocationAgentDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void importAwardAgentByExcel(AwardAllocationAgentDTO allocationAgentDTO, boolean isUpdate) {

        if (allocationAgentDTO.getAwardId() == null || allocationAgentDTO.getAwardType() == null
                || StrUtil.isBlank(allocationAgentDTO.getOssFileUrl())) {
            throw new BizException("请求参数异常，请检查！");
        }

        String ossFileUrl = allocationAgentDTO.getOssFileUrl();
        List<AgentAwardNumDTO> agentNumList = getAgentNumList(ossFileUrl);
        if (CollUtil.isEmpty(agentNumList)) {
            throw new BizException("导入文档为空！");
        }
        agentNumList = agentNumList.stream().filter(item -> StrUtil.isNotBlank(item.getAgentNo())
                && (item.getNum() != null && item.getNum() > 0) && StrUtil.isNotBlank(item.getIsChannelDisplayVal())).toList();
        if (CollUtil.isEmpty(agentNumList)) {
            throw new BizException("导入文档中有数据为空！");
        }
        //按机构号分组
        Map<String, List<AgentAwardNumDTO>> agentNumMap = agentNumList.stream().collect(Collectors.groupingBy(AgentAwardNumDTO::getAgentNo));
        //判断文件中是否存在重复的机构号
        if (agentNumMap.size() != agentNumList.size()) {
            throw new BizException("导入文档中存在重复的机构号！");
        }
        Set<String> agentNoSet = agentNumMap.keySet();
        //查询机构
        List<AgentInfoEntity> agentInfoEntityList = agentInfoService.listByIds(agentNoSet);
        if (CollUtil.isEmpty(agentInfoEntityList)) {
            throw new BizException("导入文档中机构号全部都不存在！");
        }

        //一个机构号对应一个实体类
        Map<String, AgentInfoEntity> agentInfoMap = agentInfoEntityList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, entity -> entity));
        if (agentNoSet.size() != agentInfoEntityList.size()) {
            agentNoSet.remove(agentInfoMap.keySet());
            throw new BizException(String.format("导入文档中机构号部分不存在：%s", agentNoSet));
        }
//        for (int i = 0; i < agentNumList.size(); i++) {
//            if (!agentInfoMap.containsKey(agentNumList.get(i).getAgentNo())){
//                pcWsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), agentNumList.size(), "导入文档", "第" + (i + 1) + "行，机构号不存在！", WebSocketConstants.ImportStatus.FAIL);
//            }else {
//                pcWsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), agentNumList.size(), "导入文档", "第" + (i + 1) + "行，新增成功！", WebSocketConstants.ImportStatus.SUCCESS);
//            }
//        }
        allocationAgentDTO.setAgentAwardNumList(agentNumList);
        List<AwardAgentAllocationDTO> agentAllocationDTOS = buildTree(allocationAgentDTO, agentInfoMap, isUpdate);
        allocationAgentDTO.setList(agentAllocationDTOS);
        saveOrUpdateByBatch(allocationAgentDTO, isUpdate);
    }

    public List<AwardAgentAllocationDTO> buildTree(AwardAllocationAgentDTO allocationAgentDTO, Map<String, AgentInfoEntity> agentInfoMap, boolean isUpdate) {
        List<AgentAwardNumDTO> flatList = allocationAgentDTO.getAgentAwardNumList();
        Long awardId = allocationAgentDTO.getAwardId();
        Integer awardType = allocationAgentDTO.getAwardType();
        // 1. 将扁平数据转为 Map<agentNo, DTO>
        Map<String, AwardAgentAllocationDTO> nodeMap = new HashMap<>();
        for (AgentAwardNumDTO dto : flatList) {
            AwardAgentAllocationDTO node = new AwardAgentAllocationDTO();
            AgentInfoEntity agentInfo = agentInfoMap.get(dto.getAgentNo());
            node.setAgentNo(dto.getAgentNo());
            node.setAgentNo1(agentInfo.getAgentNo1());
            node.setAgentNo2(agentInfo.getAgentNo2());
            node.setAgentNo3(agentInfo.getAgentNo3());
            node.setAgentNo4(agentInfo.getAgentNo4());
            node.setNum(dto.getNum());
            node.setIsChannelDisplay("是".equals(dto.getIsChannelDisplayVal()) ? 1 : 0);
            AwardAgentEntity awardAgentEntity = this.getOne(AwardAgentEntity.gw().eq(AwardAgentEntity::getAgentNo, dto.getAgentNo())
                    .eq(AwardAgentEntity::getAwardId, awardId)
                    .eq(AwardAgentEntity::getAwardType, awardType)
                    .eq(AwardAgentEntity::getAgentNo, dto.getAgentNo()));
            if (awardAgentEntity != null) {
                //如果存在则更新
                node.setAwardAgentId(awardAgentEntity.getAwardAgentId());
            }
            node.setChildren(new ArrayList<>());
            nodeMap.put(dto.getAgentNo(), node);
        }

        // 2. 构建父子关系
        List<AwardAgentAllocationDTO> rootNodes = new ArrayList<>();
        for (AwardAgentAllocationDTO node : nodeMap.values()) {
            String parentAgentNo = getParentAgentNo(node.getAgentNo(), agentInfoMap);
            if (parentAgentNo == null) {
                rootNodes.add(node); // 根节点（无父级）
            } else if (nodeMap.containsKey(parentAgentNo)) {
                nodeMap.get(parentAgentNo).getChildren().add(node); // 子节点
            } else {
                //无上级，直接跳级分配数量
                throw new BizException("请核实文件中机构是否按层级分配数量！");
            }
        }

        return rootNodes;
    }

    private String getParentAgentNo(String agentNo, Map<String, AgentInfoEntity> agentInfoMap) {
        AgentInfoEntity agentInfo = agentInfoMap.get(agentNo);
        AgentInfoEntity parentAgent = agentInfoMap.get(agentInfo.getPid());
        if (parentAgent == null) {
            return null;
        }
        return parentAgent.getAgentNo();
    }

    /**
     * 通过导入的oss文件获取可核销商户列表
     *
     * @return
     */
    public List<AgentAwardNumDTO> getAgentNumList(String ossFileUrl) {
        File file = FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        HttpUtil.downloadFile(ossFileUrl, file);

        // 添加oos上传记录
        OssRecordEntity ossRecordEntity = new OssRecordEntity();
        ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.UPLOAD);
        ossRecordEntity.setOssUrl(ossFileUrl);
        ossRecordEntity.setFileSize(file.length());
        ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.COUPON_MCH_TYPE);
        ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
        ossRecordEntity.setCreatedAt(new Date());
        ossRecordService.save(ossRecordEntity);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("机构号", "agentNo");
        reader.addHeaderAlias("分配数量", "num");
        reader.addHeaderAlias("渠道码是否可见", "isChannelDisplayVal");
        List<AgentAwardNumDTO> resultList = reader.readAll(AgentAwardNumDTO.class);
        reader.close();
        FileUtil.del(file);
        return resultList;
    }


    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdateOneAgentAwardNum(AwardAgentDTO awardAgentDTO) {
        if (awardAgentDTO.getAwardId() == null || awardAgentDTO.getAwardType() == null
                || StrUtil.isBlank(awardAgentDTO.getAgentNo()) || awardAgentDTO.getNum() == null
                || awardAgentDTO.getIsChannelDisplay() == null) {
            throw new BizException("请求参数异常，请检查！");
        }
        if (awardAgentDTO.getNum() <= 0) {
            throw new BizException("输入分配的数量不合理");
        }
        String allocationAgentNo = awardAgentDTO.getAgentNo();
        AwardAgentEntity allocationAwardAgent = this.getOne(AwardAgentEntity.gw()
                .eq(AwardAgentEntity::getAwardId, awardAgentDTO.getAwardId())
                .eq(AwardAgentEntity::getAwardType, awardAgentDTO.getAwardType())
                .eq(AwardAgentEntity::getAgentNo, allocationAgentNo));
        log.info("新增或追加的机构id：{}，库中数据：{}", allocationAgentNo, allocationAwardAgent);
        if (allocationAwardAgent == null) {
            //新增操作
            addOneAgentAwardNum(awardAgentDTO, null, false);
            return;
        }
        //更新操作
        addOneAgentAwardNum(awardAgentDTO, allocationAwardAgent, true);
    }

    public void addOneAgentAwardNum(AwardAgentDTO awardAgentDTO, AwardAgentEntity allocationAwardAgent, boolean isUpdate) {

        //所分配的机构id
        String allocationAgentNo = awardAgentDTO.getAgentNo();

        //若是追加操作，则机构分配的数量不能减少
        if (isUpdate && allocationAwardAgent.getNum() >= awardAgentDTO.getNum()) {
            throw new BizException("不能减少该机构已分配的奖品数量！");
        }

        Integer awardType = awardAgentDTO.getAwardType();
        Long awardId = awardAgentDTO.getAwardId();
        Object awardObject;
        Integer awardNum = null;
        String agentNo = null;

        switch (awardType) {
            case Constants.AWARD.COUPON:
                AwardCouponEntity awardCouponEntity = awardCouponService.getById(awardId);
                if (awardCouponEntity != null) {
                    awardNum = awardCouponEntity.getCouponNum();
                    agentNo = awardCouponEntity.getAgentNo();
                }
                awardObject = awardCouponEntity;
                break;
            case Constants.AWARD.GOODS:
                AwardGoodsEntity awardGoodsEntity = awardGoodsService.getById(awardId);
                if (awardGoodsEntity != null) {
                    awardNum = awardGoodsEntity.getGoodsNum();
                    agentNo = awardGoodsEntity.getAgentNo();
                }
                awardObject = awardGoodsEntity;
                break;
            case Constants.AWARD.SCORE:
                AwardScoreEntity awardScoreEntity = awardScoreService.getById(awardId);
                if (awardScoreEntity != null) {
                    awardNum = awardScoreEntity.getScoreNum();
                    agentNo = awardScoreEntity.getAgentNo();
                }
                awardObject = awardScoreEntity;
                break;
            case Constants.AWARD.VIRTUAL_COUPON:
                AwardVirtualEntity awardVirtualEntity = awardVirtualService.getById(awardId);
                if (awardVirtualEntity != null) {
                    awardNum = awardVirtualEntity.getGoodsNum();
                    agentNo = awardVirtualEntity.getAgentNo();
                }
                awardObject = awardVirtualEntity;
                break;
            default:
                throw new BizException("不支持的奖品类型！");
        }

        if (awardObject == null) {
            throw new BizException("该奖品不存在！");
        }
        if (awardNum == null) {
            throw new BizException("该奖品配置数量不存在！");
        }
        if (StrUtil.equals(allocationAgentNo, agentNo)) {
            throw new BizException("请选择当前机构的下级进行分配数量！");
        }

        //请求分配的奖品数量
        Integer requestAwardNum = awardAgentDTO.getNum();
        log.info("奖品配置机构，新增单个机构配置数量：{}，数据库中配置数量：{}", requestAwardNum, awardNum);
        if (requestAwardNum > awardNum) {
            throw new BizException("奖品配置数量不足！");
        }

        //分配数量的机构信息
        AgentInfoEntity allocationAgent = agentInfoService.getAgentInfo(allocationAgentNo);
        if (allocationAgent == null) {
            throw new BizException("请选择正确的机构！");
        }

        //根节点机构信息 以及 分配数量信息
        AgentInfoEntity rootAgent = agentInfoService.getAgentInfo(agentNo);
        AwardAgentEntity rootAwardAgent = this.getOne(AwardAgentEntity.gw()
                .eq(AwardAgentEntity::getAwardId, awardId)
                .eq(AwardAgentEntity::getAwardType, awardType)
                .eq(AwardAgentEntity::getAgentNo, agentNo));

        if (rootAwardAgent == null) {
            rootAwardAgent = createAwardAgentEntity(awardId, awardType, rootAgent, awardNum, 1);
        }

        int addNum = requestAwardNum;
        if (isUpdate) {
            addNum = requestAwardNum - allocationAwardAgent.getNum();
        }
        //奖品剩余可配置数量
        int surplusNum = rootAwardAgent.getNum() - rootAwardAgent.getNumAllocation();
        if (surplusNum < addNum) {
            //获取所分配机构对象的上级分配情况
            AwardAgentEntity parentAwardAgent = getOne(AwardAgentEntity.gw()
                    .eq(AwardAgentEntity::getAwardId, awardId)
                    .eq(AwardAgentEntity::getAwardType, awardType)
                    .eq(AwardAgentEntity::getAgentNo, allocationAgent.getPid()));
            if (parentAwardAgent != null) {
                int parentSurplusNum = parentAwardAgent.getNum() - parentAwardAgent.getNumAllocation();
                if (parentSurplusNum < addNum) {
                    throw new BizException("该奖品配置数量不足！");
                }
            }
        }

        Integer level = allocationAgent.getLevel();
        Integer rootLevel = rootAgent.getLevel();
        int distance = level - rootLevel;

        if (distance <= 0 || distance > 3) {
            throw new BizException("请选择正确的机构！");
        }

        if (distance == 1) {
            validateAndHandleLevel1(allocationAgent, rootAgent, awardAgentDTO, allocationAwardAgent, isUpdate, rootAwardAgent);
        } else if (distance == 2) {
            validateAndHandleLevel2(allocationAgent, rootAgent, awardAgentDTO, allocationAwardAgent, isUpdate, rootAwardAgent);
        } else {
            validateAndHandleLevel3(allocationAgent, rootAgent, awardAgentDTO, allocationAwardAgent, isUpdate, rootAwardAgent);
        }

        saveOrUpdate(rootAwardAgent);

        AwardSettingEntity awardSetting = awardSettingService.getOne(AwardSettingEntity.gw()
                .eq(AwardSettingEntity::getAwardId, awardId)
                .eq(AwardSettingEntity::getAwardType, awardType));
        if (awardSetting != null) {
            awardSetting.setIsAllocation(1);
            awardSettingService.updateById(awardSetting);
        }
    }

    /**
     * 处理下一级机构分配逻辑
     * @param allocationAgent 分配机构奖品数量的机构信息
     * @param rootAgent 奖品分配的根节点机构信息
     * @param dto 请求分配的信息
     * @param allocationAwardAgent 当前分配的奖品机构分配详情
     * @param isUpdate 是否更新
     * @param rootAwardAgent 奖品分配的根节点机构奖品详情
     */
    private void validateAndHandleLevel1(AgentInfoEntity allocationAgent, AgentInfoEntity rootAgent, AwardAgentDTO dto,
                                         AwardAgentEntity allocationAwardAgent, boolean isUpdate, AwardAgentEntity rootAwardAgent) {
        if (!allocationAgent.getPid().equals(rootAgent.getAgentNo())) {
            throw new BizException("请选择正确的机构！");
        }
        if (isUpdate) {
            //若为更新操作，则根节点分配下级数量的增量为 下一级新分配的数量 减去 原分配的数量
            int addNum = dto.getNum() - allocationAwardAgent.getNum();
            rootAwardAgent.setNumAllocation(rootAwardAgent.getNumAllocation() + addNum);
            allocationAwardAgent.setNum(dto.getNum());
        } else {
            //若为新增操作，则根节点分配下级数量为 根节点已分配数量 加上 新分配下级数量
            rootAwardAgent.setNumAllocation(rootAwardAgent.getNumAllocation() + dto.getNum());
            allocationAwardAgent = createAwardAgentEntity(dto.getAwardId(), dto.getAwardType(), allocationAgent,
                    dto.getNum(), dto.getIsChannelDisplay());
        }
        saveOrUpdate(allocationAwardAgent);
    }

    /**
     * 处理下下级机构分配逻辑
     * @param allocationAgent 分配机构奖品数量的机构信息
     * @param rootAgent 奖品分配的根节点机构信息
     * @param dto 请求分配的信息
     * @param allocationAwardAgent 当前分配的奖品机构分配详情
     * @param isUpdate 是否更新
     * @param rootAwardAgent 奖品分配的根节点机构奖品详情
     */
    private void validateAndHandleLevel2(AgentInfoEntity allocationAgent, AgentInfoEntity rootAgent, AwardAgentDTO dto,
                                         AwardAgentEntity allocationAwardAgent, boolean isUpdate, AwardAgentEntity rootAwardAgent) {

        AgentInfoEntity parentAgent = agentInfoService.getAgentInfo(allocationAgent.getPid());
        if (parentAgent == null || !parentAgent.getPid().equals(rootAgent.getAgentNo())) {
            throw new BizException("请选择正确的机构！");
        }

        // 查询父级机构分配记录
        AwardAgentEntity parentAwardAgent = this.getOne(AwardAgentEntity.gw()
                .eq(AwardAgentEntity::getAwardId, dto.getAwardId())
                .eq(AwardAgentEntity::getAwardType, dto.getAwardType())
                .eq(AwardAgentEntity::getAgentNo, parentAgent.getAgentNo()));

        if (parentAwardAgent == null) {
            //如果父级机构没有分配记录，则默认创建
            parentAwardAgent = createAwardAgentEntity(dto.getAwardId(), dto.getAwardType(), parentAgent, dto.getNum(), 1);
            //根节点分配下级数量
            rootAwardAgent.setNumAllocation(rootAwardAgent.getNumAllocation() + dto.getNum());
        }

        // 请求分配的数量
        int allocationNum = dto.getNum();
        //父级机构已分配数量
        Integer parentAllocationNum = parentAwardAgent.getNumAllocation();
        if (isUpdate) {
            //追加机构分配数量的增量
            int addAllocationNum = allocationNum - allocationAwardAgent.getNum();
            parentAllocationNum = parentAllocationNum + addAllocationNum;
        } else {
            parentAllocationNum = parentAllocationNum + allocationNum;
        }
        parentAwardAgent.setNumAllocation(parentAllocationNum);

        if (parentAllocationNum > parentAwardAgent.getNum()) {
            //如果更新后的父级分配数量大于父级奖品数量，则根节点分配数量的增量为 更新后的父级分配数量 - 父级奖品数量
            int addNum = parentAllocationNum - parentAwardAgent.getNum();
            rootAwardAgent.setNumAllocation(rootAwardAgent.getNumAllocation() + addNum);
            //更新父级奖品数量
            parentAwardAgent.setNum(parentAllocationNum);
        }

        saveOrUpdate(parentAwardAgent);

        // 处理当前机构的新增/更新
        handleCurrentAgent(allocationAwardAgent, dto, isUpdate, allocationAgent);
    }

    /**
     * 处理跳级分配逻辑
     */
    private void validateAndHandleLevel3(AgentInfoEntity allocationAgent, AgentInfoEntity rootAgent, AwardAgentDTO dto,
                                         AwardAgentEntity allocationAwardAgent, boolean isUpdate, AwardAgentEntity rootAwardAgent) {
        // 根节点必须是一级机构
        if (!rootAgent.getAgentNo().equals(allocationAgent.getAgentNo1())) {
            throw new BizException("请选择正确的机构！");
        }
        //请求分配的奖品数量
        Integer requestAwardNum = dto.getNum();

        // 处理三级机构分配
        requestAwardNum = handleSubLevelAgent(allocationAgent.getAgentNo3(), dto.getAwardId(), dto.getAwardType(), requestAwardNum);

        // 处理二级机构分配
        requestAwardNum = handleSubLevelAgent(allocationAgent.getAgentNo2(), dto.getAwardId(), dto.getAwardType(), requestAwardNum);

        //更新根节点已分配下级的数量
        rootAwardAgent.setNumAllocation(rootAwardAgent.getNumAllocation() + requestAwardNum);

        // 处理当前机构的新增/更新
        handleCurrentAgent(allocationAwardAgent, dto, isUpdate, allocationAgent);
    }

    /**
     * 通用子级机构处理逻辑
     */
    private int handleSubLevelAgent(String targetAgentNo, Long awardId, Integer awardType, Integer requestAwardNum) {
        AwardAgentEntity subAgentEntity = this.getOne(AwardAgentEntity.gw()
                .eq(AwardAgentEntity::getAwardId, awardId)
                .eq(AwardAgentEntity::getAwardType, awardType)
                .eq(AwardAgentEntity::getAgentNo, targetAgentNo));

        AgentInfoEntity subAgentInfo = agentInfoService.getAgentInfo(targetAgentNo);

        if (subAgentEntity == null) {
            subAgentEntity = createAwardAgentEntity(awardId, awardType, subAgentInfo, requestAwardNum, 1);
        }

        int allocationNum = subAgentEntity.getNumAllocation() + requestAwardNum;
        subAgentEntity.setNumAllocation(allocationNum);

        if (allocationNum > subAgentEntity.getNum()) {
            //根节点的已分配下级数量的增量值
            requestAwardNum = allocationNum - subAgentEntity.getNum();
            subAgentEntity.setNum(allocationNum);
        } else if (subAgentEntity.getAwardAgentId() != null){
            requestAwardNum = 0;
        }

        saveOrUpdate(subAgentEntity);
        return requestAwardNum;
    }

    /**
     * 处理当前机构新增/更新
     */
    private void handleCurrentAgent(AwardAgentEntity entity, AwardAgentDTO dto,
                                    boolean isUpdate, AgentInfoEntity allocationAgent) {
        if (isUpdate) {
            entity.setNum(dto.getNum());
        } else {
            entity = createAwardAgentEntity(dto.getAwardId(), dto.getAwardType(), allocationAgent,
                    dto.getNum(), dto.getIsChannelDisplay());
        }
        saveOrUpdate(entity);
    }

    private AwardAgentEntity createAwardAgentEntity(Long awardId, Integer awardType, AgentInfoEntity agent,
                                                    Integer num, Integer isChannelDisplay) {
        return new AwardAgentEntity()
                .setAwardId(awardId)
                .setAwardType(awardType)
                .setAgentNo(agent.getAgentNo())
                .setNum(num)
                .setNumAllocation(0)
                .setAgentNo1(agent.getAgentNo1())
                .setAgentNo2(agent.getAgentNo2())
                .setAgentNo3(agent.getAgentNo3())
                .setAgentNo4(agent.getAgentNo4())
                .setIsChannelDisplay(isChannelDisplay);
    }

    /**
     * 更新奖品配置信息  渠道码是否可见
     */
    public void updateEmpChannelDisplay(AwardAgentDTO awardAgentDTO) {
        if (awardAgentDTO.getIsChannelDisplay() == null || awardAgentDTO.getAwardAgentId() == null) {
            throw new BizException("请求参数异常，请检查！");
        }
        AwardAgentEntity awardAgentEntity = getById(awardAgentDTO.getAwardAgentId());
        if (awardAgentEntity == null) {
            throw new BizException("该记录不存在！");
        }
        awardAgentEntity.setIsChannelDisplay(awardAgentDTO.getIsChannelDisplay());
        log.info("更新奖品配置信息：{}", awardAgentEntity);
        updateById(awardAgentEntity);
    }

    /**
     * 删除单个奖品配置信息
     */
    public void removeOneAwardAgent(AwardAgentDTO awardAgentDTO) {
        if (awardAgentDTO.getAwardAgentId() == null) {
            throw new BizException("请求参数异常，请检查！");
        }
        AwardAgentEntity awardAgentEntity = getById(awardAgentDTO.getAwardAgentId());
        if (awardAgentEntity == null) {
            throw new BizException("该记录不存在！");
        }
        Integer awardType = awardAgentEntity.getAwardType();
        Long awardId = awardAgentEntity.getAwardId();
        List<ActivityAwardEntity> list = activityAwardService.list(ActivityAwardEntity.gw()
                .eq(ActivityAwardEntity::getAwardId, awardId)
                .eq(ActivityAwardEntity::getAwardType, awardType));
        if (!list.isEmpty()) {
            throw new BizException("该奖品已配置活动，不能删除！");
        }

        String errorMsg = "";
        switch (awardType) {
            case Constants.AWARD.COUPON:
                AwardCouponEntity awardCouponEntity = awardCouponService.getById(awardId);
                if (awardCouponEntity == null || awardCouponEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.GOODS:
                AwardGoodsEntity awardGoodsEntity = awardGoodsService.getById(awardId);
                if (awardGoodsEntity == null || awardGoodsEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.SCORE:
                AwardScoreEntity awardScoreEntity = awardScoreService.getById(awardId);
                if (awardScoreEntity == null || awardScoreEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
            case Constants.AWARD.VIRTUAL_COUPON:
                AwardVirtualEntity awardVirtualEntity = awardVirtualService.getById(awardId);
                if (awardVirtualEntity == null || awardVirtualEntity.getState() == Constants.AWARD_STATE.ONLINE) {
                    errorMsg = "该奖品不存在或为上线状态，不能删除！";
                }
                break;
        }

        if (!errorMsg.isEmpty()) {
            throw new BizException(errorMsg);
        }
        //是否存在已配置的下级机构
        AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(awardAgentEntity.getAgentNo());
        Integer level = agentInfo.getLevel();
        if (level != 4) {
            LambdaQueryWrapper<AwardAgentEntity> queryWrapper = AwardAgentEntity.gw()
                    .eq(AwardAgentEntity::getAwardId, awardId)
                    .eq(AwardAgentEntity::getAwardType, awardType);
            switch (level) {
                case 1:
                    queryWrapper.eq(AwardAgentEntity::getAgentNo1, agentInfo.getAgentNo())
                            .ne(AwardAgentEntity::getAgentNo2, "0");
                    break;
                case 2:
                    queryWrapper.eq(AwardAgentEntity::getAgentNo2, agentInfo.getAgentNo())
                            .ne(AwardAgentEntity::getAgentNo3, "0");
                    break;
                case 3:
                    queryWrapper.eq(AwardAgentEntity::getAgentNo3, agentInfo.getAgentNo())
                            .ne(AwardAgentEntity::getAgentNo4, "0");
                    break;
            }
            List<AwardAgentEntity> agentEntityList = list(queryWrapper);
            if (CollUtil.isNotEmpty(agentEntityList)) {
                throw new BizException("请先删除已配置的下级机构！");
            }
        }

        removeById(awardAgentDTO.getAwardAgentId());
        //更新上级已分配数量
        AwardAgentEntity parentAwardAgent = getOne(AwardAgentEntity.gw()
                .eq(AwardAgentEntity::getAwardId, awardId)
                .eq(AwardAgentEntity::getAwardType, awardType)
                .eq(AwardAgentEntity::getAgentNo, agentInfo.getPid()));
        if (parentAwardAgent != null) {
            parentAwardAgent.setNumAllocation(parentAwardAgent.getNumAllocation() - awardAgentEntity.getNum());
            updateById(parentAwardAgent);
        }
    }
}
